#pragma once
#include "GameComponent.hpp"
#include "Property.hpp"
#include "DirtyProperty.hpp"
#include "Vector3.hpp"
#include "Quaternion.hpp"
#include "Matrix4x4.hpp"
#include "ICellItem.hpp"

namespace Typhoon {
	class Transform : public GameComponent<Transform>, public ICellItem {
	public:
		Transform();

		Property<Transform*, Vector3> Position;  
		Property<Transform*, Quaternion> Rotation; 
		Property<Transform*, Vector3> Anchor; 
		Property<Transform*, Matrix4x4> Matrix;

		DirtyProperty<Transform*, Matrix4x4> Local;
		DirtyProperty<Transform*, Matrix4x4> World;
		DirtyProperty<Transform*, Matrix4x4> WorldInverse;

		void HookOther(Transform* other);
		void UnHookOther(Transform* other);


	private:
		void PropertyChanged(Transform* transform);
		void CalcLocal(DirtyProperty<Transform*, Matrix4x4>::EventData& event);
		void CalcWorld(DirtyProperty<Transform*, Matrix4x4>::EventData& event);
		void CalcWorldInverse(DirtyProperty<Transform*, Matrix4x4>::EventData& event);

		void OtherWorldChanged(DirtyProperty<Transform*, Matrix4x4>* event);

	};
}